<template>
  <div>
    <v-stage 
      :config="stageConfig" 
      @mousedown="handleStageMouseDown" 
      @mousemove="handleStageMouseMove" 
      @mouseup="handleStageMouseUp"
    >
      <!-- 背景图层 -->
      <v-layer>
        <v-rect
          :config="{
            width: stageConfig.width,
            height: stageConfig.height,
            fill: 'transparent',
            x: 0,
            y: 0,
            listening: false  // 禁用背景的事件监听
          }"
        />
      </v-layer>
      <!-- 绘制图层 -->
      <v-layer ref="layerRef">
        <!-- 曲线 -->
        <v-line
          v-for="(line, i) in lines"
          :key="'line-' + i"
          :config="line"
          :draggable="isDraggable"
          @dragend="onShapeDragEnd(i, 'line')"
        />
        <!-- 箭头 -->
        <template v-for="(arrow, i) in arrows" :key="'arrow-' + i">
          <v-line
            :config="arrow.line"
            :draggable="isDraggable"
            @dragend="(evt) => onShapeDragEnd(i, 'arrow', evt)"
          />
          <v-arrow
            :config="arrow"
            :draggable="isDraggable"
            @dragend="(evt) => onShapeDragEnd(i, 'arrow', evt)"
          />
        </template>

        <!-- 绘制中的临时图形 -->
        <v-line 
          v-if="isDrawing && tool === 'pen' && tempShape"
          :config="tempShape"
        />
        <!-- 绘制中的临时箭头 -->
        <template v-if="isDragging && tool === 'arrow' && tempShape">
          <!-- 只使用 v-arrow 绘制临时箭头 -->
          <v-arrow
            :config="tempShape"
          />
        </template>
      </v-layer>
    </v-stage>
    <div class="toolbar">
      <div class="tool-group">
        <button @click="tool='pen'" :class="{ active: tool === 'pen' }">曲线</button>
        <button @click="tool='arrow'" :class="{ active: tool === 'arrow' }">箭头</button>
        <button @click="clearAll">清除</button>
        <button @click="toggleDraggable" :class="{ active: isDraggable }">
          {{ isDraggable ? '锁定' : '解锁' }}
        </button>
      </div>
      <div class="tool-group">
        <label>线宽：</label>
        <input 
          type="range" 
          v-model="strokeWidth" 
          min="1" 
          max="20" 
          step="1"
        />
        <span>{{ strokeWidth }}px</span>
      </div>
      <div class="tool-group">
        <label>颜色：</label>
        <input 
          type="color" 
          v-model="strokeColor"
        />
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, reactive, onMounted } from 'vue'

const stageConfig = reactive({ width: 800, height: 600 })
const tool = ref('pen')
const lines = ref([])
const arrows = ref([]) // 现在 arrows 数组将存储单个 v-arrow 的配置对象
const isDrawing = ref(false)
const isDragging = ref(false)
let currentLine = null
const currentArrow = ref(null)
const startArrowPoint = reactive({ x: 0, y: 0 })
const layerRef = ref(null)
const strokeWidth = ref(2)
const strokeColor = ref('#000000')

// 新增：用于存储正在绘制的临时图形
// tempShape 现在将存储单个 v-arrow 的配置
const tempShape = ref(null)

// 标记正在拖动的图形的原始位置偏移量
const dragStartPos = ref(null)

const isDraggable = ref(true) // 新增：控制图形是否可拖动

function handleStageMouseDown(e) {
  // 检查点击目标是否是 Konva Shape 实例
  const target = e.target;
  const type = target.getType ? target.getType() : '';
  
  if (type && type !== 'Stage' && type !== 'Layer') {
      console.log('Clicked on existing shape', type);
      return;  // 如果点击的是已绘制图形，不开始新的绘制
  }

  const stage = e.target.getStage();
  if (!stage) {
    console.error('Stage not found');
    return;
  }

  const pos = stage.getPointerPosition();
  if (!pos) {
    console.error('Pointer position not found');
    return;
  }

  console.log('handleStageMouseDown', { tool: tool.value, isDrawing: isDrawing.value, pos });

  if (tool.value === 'pen') {
    isDrawing.value = true;
    tempShape.value = {
      points: [pos.x, pos.y],
      stroke: strokeColor.value,
      strokeWidth: strokeWidth.value,
      lineCap: 'round',
      lineJoin: 'round',
      draggable: true,
    };
    console.log('MouseDown: Created tempShape (pen)', tempShape.value);
  } else if (tool.value === 'arrow') {
    // 只记录起始点，不立即创建临时箭头
    startArrowPoint.x = pos.x;
    startArrowPoint.y = pos.y;
    isDragging.value = true;  // 标记开始拖动
    console.log('Arrow start point:', startArrowPoint);

    // 鼠标按下时创建一个空的临时箭头配置，在 mousemove 时更新
    tempShape.value = {
      points: [pos.x, pos.y, pos.x, pos.y], // 初始点与起始点相同
      stroke: strokeColor.value,
      fill: strokeColor.value, // 填充颜色通常与描边颜色相同
      strokeWidth: strokeWidth.value, // 箭身线条宽度
      pointerLength: 0, // 初始时箭头头部长度为0
      pointerWidth: 0,  // 初始时箭头头部宽度为0
      lineJoin: 'round',
      lineCap: 'round',
      draggable: true,
    };
    console.log('MouseDown: Created initial tempShape (arrow)', tempShape.value);
  }
}

function handleStageMouseUp(e) {
  console.log('handleStageMouseUp', { isDrawing: isDrawing.value, isDragging: isDragging.value, tool: tool.value, tempShape: tempShape.value });

  if (isDrawing.value || isDragging.value) {
    // 检查是否进行了拖动
    const stage = e.target.getStage();
    const pos = stage.getPointerPosition();
    const distance = Math.sqrt(
      Math.pow(pos.x - startArrowPoint.x, 2) +
      Math.pow(pos.y - startArrowPoint.y, 2)
    );

    // 如果距离太小，认为是点击而不是拖动
    if (tool.value === 'arrow' && distance < 10) { // 增加点击阈值，避免误触
      console.log('MouseUp: Click detected, not creating arrow');
      isDragging.value = false;
      tempShape.value = null;
      return;
    }

    isDrawing.value = false;
    isDragging.value = false;

   if (tempShape.value) {
     if (tool.value === 'pen' && !Array.isArray(tempShape.value)) {
       // 对于画笔，如果点数量足够，添加到最终数组
       if (tempShape.value.points.length > 2) {
         lines.value.push(tempShape.value);
        console.log('MouseUp: Added pen to lines', lines.value.length);
       }
      } else if (tool.value === 'arrow' && tempShape.value.points.length === 4) { // 检查是否是有效的箭头临时形状
        // 对于箭头，检查长度是否有效
        const startX = tempShape.value.points[0];
        const startY = tempShape.value.points[1];
        const endX = pos.x; // 终点是鼠标释放位置
        const endY = pos.y;

        // 重新计算箭身长度，确保使用鼠标释放时的最终位置
        const currentLength = Math.sqrt(Math.pow(endX - startX, 2) + Math.pow(endY - startY, 2));

        // 计算箭头头部大小（与线条宽度成比例），并调整比例
        const arrowSize = Math.max(18, strokeWidth.value * 1.8); // 调整比例因子
        const minLength = arrowSize + 5; // 最小长度应大于箭头头部长度

        if (currentLength > minLength) {
          // 计算箭身线条的终点，使其正好在箭头头部的基部
          const dx = endX - startX;
          const dy = endY - startY;
          const angle = Math.atan2(dy, dx);

          let lineEndX = endX;
          let lineEndY = endY;

          // 只有当箭身长度大于箭头头部长度时才计算箭身终点
          if (currentLength > arrowSize) {
             // 使用向量和比例精确计算箭身终点
             const ratio = (currentLength - arrowSize) / currentLength;
             lineEndX = startX + dx * ratio;
             lineEndY = startY + dy * ratio;
          } else {
             // 如果箭身太短，箭身线条长度为0，终点设为起点
             lineEndX = startX;
             lineEndY = startY;
          }

          // 创建新的箭头对象，避免引用问题
          const newArrow = { // 确保创建一个新的独立对象
            points: [startX, startY, lineEndX, lineEndY], // 箭身从起点到计算出的终点
            stroke: tempShape.value.stroke,
            fill: tempShape.value.fill,
            strokeWidth: tempShape.value.strokeWidth,
            pointerLength: arrowSize,
            pointerWidth: arrowSize, // 箭头头部的宽度，尝试与长度相等
            lineJoin: tempShape.value.lineJoin,
            lineCap: tempShape.value.lineCap,
            draggable: true
          };
          // 使用数组解构来触发响应式更新
          arrows.value = [...arrows.value, newArrow];
          console.log('MouseUp: arrows array after adding new arrow:', arrows.value);
       } else {
          console.log('MouseUp: Arrow too short, not added', { currentLength, minLength });
       }
     }
     // 清空临时图形引用
     tempShape.value = null;
    console.log('MouseUp: Cleared tempShape');
   }
    console.log('MouseUp: End', { isDrawing: isDrawing.value, isDragging: isDragging.value, tool: tool.value, tempShape: tempShape.value });
  }
}

function handleStageMouseMove(e) {
  if (!isDragging.value && !isDrawing.value) return;

  const stage = e.target.getStage();
  if (!stage) {
    console.error('Stage not found');
    return;
  }

  const pos = stage.getPointerPosition();
  if (!pos) {
    console.error('Pointer position not found');
    return;
  }

  // 检查是否进行了足够的移动
  const distance = Math.sqrt(
    Math.pow(pos.x - startArrowPoint.x, 2) +
    Math.pow(pos.y - startArrowPoint.y, 2)
  );

  if (tool.value === 'pen' && !Array.isArray(tempShape.value)) {
    // 画笔工具只更新当前临时线段的点
    tempShape.value.points.push(pos.x, pos.y);
    tempShape.value.points = [...tempShape.value.points]; // 强制响应式更新
  } else if (tool.value === 'arrow' && isDragging.value && tempShape.value) {
    // 只有当移动距离超过阈值时才创建箭头或更新其形状
    if (distance < 5) {
      // 如果移动距离太小，保持箭身长度为0，只更新终点位置和基础属性
      tempShape.value.points = [startArrowPoint.x, startArrowPoint.y, pos.x, pos.y];
      tempShape.value.strokeWidth = strokeWidth.value;
      tempShape.value.stroke = strokeColor.value;
      tempShape.value.fill = strokeColor.value;

      // 箭头头部大小和宽度设为0
      tempShape.value.pointerLength = 0;
      tempShape.value.pointerWidth = 0;
      tempShape.value.points = [...tempShape.value.points]; // 强制响应式更新
      return;
    }

    const startX = startArrowPoint.x;
    const startY = startArrowPoint.y;
    const endX = pos.x;
    const endY = pos.y;

    // 计算箭身方向和长度
    const dx = endX - startX;
    const dy = endY - startY;
    const currentLength = Math.sqrt(dx * dx + dy * dy);

    // 计算箭头头部大小（与线条宽度成比例），并调整比例
    // 使用 Math.max 确保即使线条很细，箭头也有最小尺寸
    // 再次微调比例因子和最小尺寸
    const arrowSize = Math.max(18, strokeWidth.value * 1.8); // 调整比例因子

    // 计算箭身线条的终点，使其正好在箭头头部的基部
    // 如果箭身太短不足以容纳箭头头部，箭身终点就是起点
    let lineEndX = endX;
    let lineEndY = endY;

    // 只有当箭身长度大于箭头头部长度时才计算箭身终点
    if (currentLength > arrowSize) {
      // 使用向量和比例精确计算箭身终点
      const ratio = (currentLength - arrowSize) / currentLength;
      lineEndX = startX + dx * ratio;
      lineEndY = startY + dy * ratio;
    } else {
      // 如果箭身太短，箭身线条长度为0，终点设为起点
      lineEndX = startX;
      lineEndY = startY;
    }

    // 更新临时箭头的 points
    // v-arrow 的 points 定义的是箭身，头部在第二个点
    tempShape.value.points = [startX, startY, lineEndX, lineEndY];

    // 更新临时箭头的头部大小和线条宽度
    tempShape.value.strokeWidth = strokeWidth.value;
    tempShape.value.pointerLength = arrowSize;
    tempShape.value.pointerWidth = arrowSize; // 箭头头部的宽度，尝试与长度相等
    tempShape.value.stroke = strokeColor.value;
    tempShape.value.fill = strokeColor.value;

    tempShape.value.points = [...tempShape.value.points]; // 强制响应式更新

    console.log('Arrow moving:', tempShape.value);
  }
}

// TODO: 完善复合箭头的拖动逻辑
function onShapeDragEnd(i, type, evt, j) {
  console.log('onShapeDragEnd triggered', { i, type, evt, j });
  // 拖动结束，更新 shapes 数组中对应图形的位置
  if (!evt || !evt.target) {
    console.error('onShapeDragEnd: evt or evt.target is undefined', { evt });
    return;
  }
  const node = evt.target;
  const newPos = node.position(); // 获取相对 group 或 layer 的新位置

  if (type === 'line') {
    // 对于曲线，拖动的是 v-line 本身 (当前简化的实现，没有 group)
    // 需要将 position 的偏移量应用到 points 上，并重置 position 为 {x: 0, y: 0}
    const line = lines.value[i];
    const dx = newPos.x;
    const dy = newPos.y;

    // 更新 points
    const newPoints = [];
    for (let k = 0; k < line.points.length; k += 2) {
       newPoints.push(line.points[k] + dx);
       newPoints.push(line.points[k + 1] + dy);
    }
    line.points = newPoints;
    console.log('onShapeDragEnd: line points after update:', line.points);
    // 重置 Konva 节点的 position
    node.position({ x: 0, y: 0 });
    console.log('onShapeDragEnd: node position after reset:', node.position());
    console.log('onShapeDragEnd: Updated line position', line);

  } else if (type === 'arrow') { // 修改类型检查，现在 arrows 数组存储的是单个 v-arrow
     // 对于箭头，拖动的是 v-arrow 本身
     // 需要将 position 的偏移量应用到 points 上，并重置 position 为 {x: 0, y: 0}
     const arrow = arrows.value[i];
     const dx = newPos.x;
     const dy = newPos.y;

     // 更新 points
     const newPoints = [];
     for (let k = 0; k < arrow.points.length; k += 2) {
        newPoints.push(arrow.points[k] + dx);
        newPoints.push(arrow.points[k + 1] + dy);
     }
     arrow.points = newPoints;
     // 重置 Konva 节点的 position
     node.position({ x: 0, y: 0 });
     console.log('onShapeDragEnd: node position after reset:', node.position());
     console.log('onShapeDragEnd: Updated arrow position', arrow);
  }
}

// 修改 clearAll 函数
function clearAll() {
  lines.value = [];
  arrows.value = [];
  console.log('Cleared all shapes');
}

// 新增：切换图形是否可拖动的函数
function toggleDraggable() {
  isDraggable.value = !isDraggable.value;
  // 更新所有已存在图形的可拖动状态
  lines.value.forEach(line => {
    line.draggable = isDraggable.value;
  });
  arrows.value.forEach(arrow => {
    arrow.draggable = isDraggable.value;
  });
}
</script>

<style scoped>
.toolbar {
  margin-top: 10px;
  display: flex;
  gap: 20px;
  align-items: center;
  padding: 10px;
  background: #f5f5f5;
  border-radius: 4px;
}
.tool-group {
  display: flex;
  align-items: center;
  gap: 8px;
}
button {
  padding: 6px 12px;
  border: 1px solid #ccc;
  border-radius: 4px;
  background: white;
  cursor: pointer;
}
button:hover {
  background: #f0f0f0;
}
button.active {
  background: #e0e0e0;
  border-color: #999;
}
input[type="range"] {
  width: 100px;
}
input[type="color"] {
  width: 40px;
  height: 24px;
  padding: 0;
  border: 1px solid #ccc;
  border-radius: 4px;
}
</style>
